{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-15T13:31:44.678250Z",
     "start_time": "2018-05-15T13:31:30.478350Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "import cv2\n",
    "import numpy as np\n",
    "\n",
    "from keras.models import Model\n",
    "from keras.layers import Activation, Dropout, Dense, Input, Flatten"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# load data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-15T13:31:59.734506Z",
     "start_time": "2018-05-15T13:31:47.262774Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_dataset_image_1 = np.load('smoke_data/set1_48_data.npy')\n",
    "smoke_dataset_label_1 = np.load('smoke_data/set1_48_label.npy')\n",
    "smoke_dataset_image_2 = np.load('smoke_data/set2_48_data.npy')\n",
    "smoke_dataset_label_2 = np.load('smoke_data/set2_48_label.npy')\n",
    "smoke_dataset_image_3 = np.load('smoke_data/set3_48_data.npy')\n",
    "smoke_dataset_label_3 = np.load('smoke_data/set3_48_label.npy')\n",
    "smoke_dataset_image_4 = np.load('smoke_data/set4_48_data.npy')\n",
    "smoke_dataset_label_4 = np.load('smoke_data/set4_48_label.npy')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-15T13:31:59.966888Z",
     "start_time": "2018-05-15T13:31:59.779259Z"
    }
   },
   "outputs": [],
   "source": [
    "training_set = smoke_dataset_image_3 * 255\n",
    "training_set_label = smoke_dataset_label_3.flatten().astype(np.int64)\n",
    "test_set = smoke_dataset_image_4 * 255\n",
    "test_set_label = smoke_dataset_label_4.flatten().astype(np.int64)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# HOG"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get Feature"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:57:57.166532Z",
     "start_time": "2018-05-14T12:57:54.164838Z"
    }
   },
   "outputs": [],
   "source": [
    "from skimage import feature as ft"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:57:59.136725Z",
     "start_time": "2018-05-14T12:57:57.213945Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/song/anaconda3/lib/python3.6/site-packages/skimage/feature/_hog.py:119: skimage_deprecation: Default value of `block_norm`==`L1` is deprecated and will be changed to `L2-Hys` in v0.15\n",
      "  'be changed to `L2-Hys` in v0.15', skimage_deprecation)\n"
     ]
    }
   ],
   "source": [
    "training_set_hog_feature = np.array([ft.hog(cv2.cvtColor(i, cv2.COLOR_BGR2GRAY)) for i in training_set])\n",
    "\n",
    "test_set_hog_feature = np.array([ft.hog(cv2.cvtColor(i, cv2.COLOR_BGR2GRAY)) for i in test_set])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Construct Fully Connected Network"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:57:59.199993Z",
     "start_time": "2018-05-14T12:57:59.183875Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_hog_input = Input(shape=(training_set_hog_feature.shape[1], ))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:57:59.318823Z",
     "start_time": "2018-05-14T12:57:59.246636Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_hog_dense = Dense(128, activation='sigmoid')(smoke_detector_hog_input)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:57:59.406357Z",
     "start_time": "2018-05-14T12:57:59.368704Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_hog_dropout = Dropout(0.3)(smoke_detector_hog_dense)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:57:59.505203Z",
     "start_time": "2018-05-14T12:57:59.453872Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_hog_prediction = Dense(1, activation='sigmoid')(smoke_detector_hog_dropout)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:57:59.606784Z",
     "start_time": "2018-05-14T12:57:59.548940Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_hog_model = Model(inputs=smoke_detector_hog_input, outputs=smoke_detector_hog_prediction)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:57:59.805794Z",
     "start_time": "2018-05-14T12:57:59.651345Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_hog_model.compile(optimizer='Adam',\n",
    "              loss='binary_crossentropy',\n",
    "              metrics=['accuracy'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-12T08:38:13.644693Z",
     "start_time": "2018-05-12T08:38:09.664694Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/30\n",
      "1383/1383 [==============================] - 0s 155us/step - loss: 0.7190 - acc: 0.5553\n",
      "Epoch 2/30\n",
      "1383/1383 [==============================] - 0s 95us/step - loss: 0.6716 - acc: 0.5936\n",
      "Epoch 3/30\n",
      "1383/1383 [==============================] - 0s 96us/step - loss: 0.6393 - acc: 0.6016\n",
      "Epoch 4/30\n",
      "1383/1383 [==============================] - 0s 91us/step - loss: 0.6094 - acc: 0.6544\n",
      "Epoch 5/30\n",
      "1383/1383 [==============================] - 0s 91us/step - loss: 0.5822 - acc: 0.6797\n",
      "Epoch 6/30\n",
      "1383/1383 [==============================] - 0s 94us/step - loss: 0.5822 - acc: 0.6544\n",
      "Epoch 7/30\n",
      "1383/1383 [==============================] - 0s 93us/step - loss: 0.5764 - acc: 0.6558\n",
      "Epoch 8/30\n",
      "1383/1383 [==============================] - 0s 102us/step - loss: 0.5521 - acc: 0.7028\n",
      "Epoch 9/30\n",
      "1383/1383 [==============================] - 0s 97us/step - loss: 0.5365 - acc: 0.6992\n",
      "Epoch 10/30\n",
      "1383/1383 [==============================] - 0s 91us/step - loss: 0.5272 - acc: 0.7122\n",
      "Epoch 11/30\n",
      "1383/1383 [==============================] - 0s 95us/step - loss: 0.5266 - acc: 0.7093\n",
      "Epoch 12/30\n",
      "1383/1383 [==============================] - 0s 84us/step - loss: 0.5151 - acc: 0.7332\n",
      "Epoch 13/30\n",
      "1383/1383 [==============================] - 0s 86us/step - loss: 0.5128 - acc: 0.7267\n",
      "Epoch 14/30\n",
      "1383/1383 [==============================] - 0s 83us/step - loss: 0.4954 - acc: 0.7484\n",
      "Epoch 15/30\n",
      "1383/1383 [==============================] - 0s 96us/step - loss: 0.4973 - acc: 0.7346\n",
      "Epoch 16/30\n",
      "1383/1383 [==============================] - 0s 85us/step - loss: 0.4856 - acc: 0.7397\n",
      "Epoch 17/30\n",
      "1383/1383 [==============================] - 0s 86us/step - loss: 0.4791 - acc: 0.7549\n",
      "Epoch 18/30\n",
      "1383/1383 [==============================] - 0s 91us/step - loss: 0.4814 - acc: 0.7585\n",
      "Epoch 19/30\n",
      "1383/1383 [==============================] - 0s 85us/step - loss: 0.4835 - acc: 0.7462\n",
      "Epoch 20/30\n",
      "1383/1383 [==============================] - 0s 86us/step - loss: 0.4669 - acc: 0.7773\n",
      "Epoch 21/30\n",
      "1383/1383 [==============================] - 0s 94us/step - loss: 0.4720 - acc: 0.7505\n",
      "Epoch 22/30\n",
      "1383/1383 [==============================] - 0s 85us/step - loss: 0.4601 - acc: 0.7679\n",
      "Epoch 23/30\n",
      "1383/1383 [==============================] - 0s 89us/step - loss: 0.4567 - acc: 0.7650\n",
      "Epoch 24/30\n",
      "1383/1383 [==============================] - 0s 82us/step - loss: 0.4638 - acc: 0.7462\n",
      "Epoch 25/30\n",
      "1383/1383 [==============================] - 0s 83us/step - loss: 0.4529 - acc: 0.7722\n",
      "Epoch 26/30\n",
      "1383/1383 [==============================] - 0s 89us/step - loss: 0.4588 - acc: 0.7636\n",
      "Epoch 27/30\n",
      "1383/1383 [==============================] - 0s 86us/step - loss: 0.4488 - acc: 0.7657\n",
      "Epoch 28/30\n",
      "1383/1383 [==============================] - 0s 86us/step - loss: 0.4397 - acc: 0.7831\n",
      "Epoch 29/30\n",
      "1383/1383 [==============================] - 0s 91us/step - loss: 0.4437 - acc: 0.7845\n",
      "Epoch 30/30\n",
      "1383/1383 [==============================] - 0s 85us/step - loss: 0.4411 - acc: 0.7780\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<keras.callbacks.History at 0x7f0109c556a0>"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "smoke_detector_hog_model.fit(training_set_hog_feature, training_set_label, epochs=30)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Test HOG Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-12T08:38:14.578736Z",
     "start_time": "2018-05-12T08:38:14.515531Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1383/1383 [==============================] - 0s 43us/step\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[0.41491538544797585, 0.80694143179957623]"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "smoke_detector_hog_model.evaluate(training_set_hog_feature, training_set_label)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-12T08:38:15.529271Z",
     "start_time": "2018-05-12T08:38:15.454856Z"
    }
   },
   "outputs": [],
   "source": [
    "training_set_label_prediction_hog = smoke_detector_hog_model.predict(training_set_hog_feature)\n",
    "test_set_label_prediction_hog = smoke_detector_hog_model.predict(test_set_hog_feature)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-12T08:38:16.396428Z",
     "start_time": "2018-05-12T08:38:16.387520Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "混淆矩阵 Training Set\n",
      "    real/predict   True    False\n",
      "    \n",
      "    smoke          442     110\n",
      "    no smoke       674     157\n",
      "    检测率：0.8007246376811594\n",
      "    虚警率：0.18892900120336945\n"
     ]
    }
   ],
   "source": [
    "training_set_label_prediction_hog_positive = training_set_label_prediction_hog[training_set_label == 1]\n",
    "training_set_label_prediction_hog_negative = training_set_label_prediction_hog[training_set_label == 0]\n",
    "\n",
    "training_set_label_prediction_hog_positive_true = training_set_label_prediction_hog_positive[training_set_label_prediction_hog_positive >= 0.5]\n",
    "training_set_label_prediction_hog_positive_false = training_set_label_prediction_hog_positive[training_set_label_prediction_hog_positive < 0.5]\n",
    "training_set_label_prediction_hog_negative_true = training_set_label_prediction_hog_negative[training_set_label_prediction_hog_negative < 0.5]\n",
    "training_set_label_prediction_hog_negative_false = training_set_label_prediction_hog_negative[training_set_label_prediction_hog_negative >= 0.5]\n",
    "\n",
    "print(\n",
    "    '''HOG+FC Training Set 混淆矩阵 Training Set\n",
    "    real/predict   True    False\n",
    "    \n",
    "    smoke          {0}     {1}\n",
    "    no smoke       {2}     {3}\n",
    "    检测率：{4}\n",
    "    虚警率：{5}'''.format(\n",
    "    training_set_label_prediction_hog_positive_true.shape[0],\n",
    "    training_set_label_prediction_hog_positive_false.shape[0],\n",
    "    training_set_label_prediction_hog_negative_true.shape[0],\n",
    "    training_set_label_prediction_hog_negative_false.shape[0],\n",
    "    training_set_label_prediction_hog_positive_true.shape[0] / training_set_label_prediction_hog_positive.shape[0],\n",
    "    training_set_label_prediction_hog_negative_false.shape[0] / training_set_label_prediction_hog_negative.shape[0]\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-12T08:38:17.451140Z",
     "start_time": "2018-05-12T08:38:17.442615Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "混淆矩阵 test Set\n",
      "    real/predict   True    False\n",
      "    \n",
      "    smoke          504     184\n",
      "    no smoke       647     170\n",
      "    检测率：0.7325581395348837\n",
      "    虚警率：0.20807833537331702\n"
     ]
    }
   ],
   "source": [
    "test_set_label_prediction_hog_positive = test_set_label_prediction_hog[test_set_label == 1]\n",
    "test_set_label_prediction_hog_negative = test_set_label_prediction_hog[test_set_label == 0]\n",
    "\n",
    "test_set_label_prediction_hog_positive_true = test_set_label_prediction_hog_positive[test_set_label_prediction_hog_positive >= 0.5]\n",
    "test_set_label_prediction_hog_positive_false = test_set_label_prediction_hog_positive[test_set_label_prediction_hog_positive < 0.5]\n",
    "test_set_label_prediction_hog_negative_true = test_set_label_prediction_hog_negative[test_set_label_prediction_hog_negative < 0.5]\n",
    "test_set_label_prediction_hog_negative_false = test_set_label_prediction_hog_negative[test_set_label_prediction_hog_negative >= 0.5]\n",
    "\n",
    "print(\n",
    "    '''HOG+FC Test Set 混淆矩阵 test Set\n",
    "    real/predict   True    False\n",
    "    \n",
    "    smoke          {0}     {1}\n",
    "    no smoke       {2}     {3}\n",
    "    检测率：{4}\n",
    "    虚警率：{5}'''.format(\n",
    "    test_set_label_prediction_hog_positive_true.shape[0],\n",
    "    test_set_label_prediction_hog_positive_false.shape[0],\n",
    "    test_set_label_prediction_hog_negative_true.shape[0],\n",
    "    test_set_label_prediction_hog_negative_false.shape[0],\n",
    "    test_set_label_prediction_hog_positive_true.shape[0] / test_set_label_prediction_hog_positive.shape[0],\n",
    "    test_set_label_prediction_hog_negative_false.shape[0] / test_set_label_prediction_hog_negative.shape[0]\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Extract Feature"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:05.829618Z",
     "start_time": "2018-05-14T12:58:05.827273Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_hog_model_feature_extraction = Model(inputs=smoke_detector_hog_input, outputs=smoke_detector_hog_dense)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-12T08:38:20.002860Z",
     "start_time": "2018-05-12T08:38:19.951927Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1383, 128)"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "smoke_detector_hog_model_feature_extraction.predict(training_set_hog_feature).shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# LBP"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get Feature"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:13.518171Z",
     "start_time": "2018-05-14T12:58:13.503291Z"
    }
   },
   "outputs": [],
   "source": [
    "class LocalBinaryPatterns:\n",
    "\tdef __init__(self, numPoints, radius):\n",
    "\t\t# store the number of points and radius\n",
    "\t\tself.numPoints = numPoints\n",
    "\t\tself.radius = radius\n",
    " \n",
    "\tdef describe(self, image, eps=1e-7):\n",
    "\t\t# compute the Local Binary Pattern representation\n",
    "\t\t# of the image, and then use the LBP representation\n",
    "\t\t# to build the histogram of patterns\n",
    "\t\tlbp = ft.local_binary_pattern(image, self.numPoints,\n",
    "\t\t\tself.radius, method=\"uniform\")\n",
    "\t\t(hist, _) = np.histogram(lbp.ravel(),\n",
    "\t\t\tbins=np.arange(0, self.numPoints + 3),\n",
    "\t\t\trange=(0, self.numPoints + 2))\n",
    " \n",
    "\t\t# normalize the histogram\n",
    "\t\thist = hist.astype(\"float\")\n",
    "\t\thist /= (hist.sum() + eps)\n",
    " \n",
    "\t\t# return the histogram of Local Binary Patterns\n",
    "\t\treturn hist"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:13.927373Z",
     "start_time": "2018-05-14T12:58:13.925307Z"
    }
   },
   "outputs": [],
   "source": [
    "lbp_descriptor = LocalBinaryPatterns(16, 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:17.473995Z",
     "start_time": "2018-05-14T12:58:15.357523Z"
    }
   },
   "outputs": [],
   "source": [
    "training_set_lbp_feature = np.array([lbp_descriptor.describe(cv2.cvtColor(i, cv2.COLOR_BGR2GRAY)) for i in training_set])\n",
    "\n",
    "test_set_lbp_feature = np.array([lbp_descriptor.describe(cv2.cvtColor(i, cv2.COLOR_BGR2GRAY)) for i in test_set])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:17.525887Z",
     "start_time": "2018-05-14T12:58:17.522570Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_lbp_input = Input(shape=(training_set_lbp_feature.shape[1], ))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:20.177709Z",
     "start_time": "2018-05-14T12:58:20.168334Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_lbp_dense = Dense(128, activation='sigmoid')(smoke_detector_lbp_input)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:20.534246Z",
     "start_time": "2018-05-14T12:58:20.518444Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_lbp_dropout = Dropout(0.3)(smoke_detector_lbp_dense)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:20.922659Z",
     "start_time": "2018-05-14T12:58:20.913551Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_lbp_prediction = Dense(1, activation='sigmoid')(smoke_detector_lbp_dropout)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:22.594449Z",
     "start_time": "2018-05-14T12:58:22.591947Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_lbp_model = Model(inputs=smoke_detector_lbp_input, outputs=smoke_detector_lbp_prediction)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:23.039227Z",
     "start_time": "2018-05-14T12:58:23.017379Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_lbp_model.compile(optimizer='AdaDelta',\n",
    "              loss='binary_crossentropy',\n",
    "              metrics=['accuracy'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-12T08:38:36.923965Z",
     "start_time": "2018-05-12T08:38:35.343185Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/30\n",
      "1383/1383 [==============================] - 0s 99us/step - loss: 0.6906 - acc: 0.5770\n",
      "Epoch 2/30\n",
      "1383/1383 [==============================] - 0s 31us/step - loss: 0.6788 - acc: 0.5813\n",
      "Epoch 3/30\n",
      "1383/1383 [==============================] - 0s 33us/step - loss: 0.6817 - acc: 0.5879\n",
      "Epoch 4/30\n",
      "1383/1383 [==============================] - 0s 31us/step - loss: 0.6647 - acc: 0.5842\n",
      "Epoch 5/30\n",
      "1383/1383 [==============================] - 0s 30us/step - loss: 0.6679 - acc: 0.5850\n",
      "Epoch 6/30\n",
      "1383/1383 [==============================] - 0s 31us/step - loss: 0.6585 - acc: 0.6146\n",
      "Epoch 7/30\n",
      "1383/1383 [==============================] - 0s 30us/step - loss: 0.6573 - acc: 0.6132\n",
      "Epoch 8/30\n",
      "1383/1383 [==============================] - 0s 33us/step - loss: 0.6587 - acc: 0.6124\n",
      "Epoch 9/30\n",
      "1383/1383 [==============================] - 0s 34us/step - loss: 0.6449 - acc: 0.6471\n",
      "Epoch 10/30\n",
      "1383/1383 [==============================] - 0s 31us/step - loss: 0.6421 - acc: 0.6276\n",
      "Epoch 11/30\n",
      "1383/1383 [==============================] - 0s 33us/step - loss: 0.6284 - acc: 0.6443\n",
      "Epoch 12/30\n",
      "1383/1383 [==============================] - 0s 32us/step - loss: 0.6311 - acc: 0.6392\n",
      "Epoch 13/30\n",
      "1383/1383 [==============================] - 0s 31us/step - loss: 0.6189 - acc: 0.6616\n",
      "Epoch 14/30\n",
      "1383/1383 [==============================] - 0s 31us/step - loss: 0.6099 - acc: 0.6631\n",
      "Epoch 15/30\n",
      "1383/1383 [==============================] - 0s 30us/step - loss: 0.6139 - acc: 0.6565\n",
      "Epoch 16/30\n",
      "1383/1383 [==============================] - 0s 29us/step - loss: 0.6012 - acc: 0.6746\n",
      "Epoch 17/30\n",
      "1383/1383 [==============================] - 0s 30us/step - loss: 0.5976 - acc: 0.6847\n",
      "Epoch 18/30\n",
      "1383/1383 [==============================] - 0s 34us/step - loss: 0.5799 - acc: 0.6978\n",
      "Epoch 19/30\n",
      "1383/1383 [==============================] - 0s 32us/step - loss: 0.5853 - acc: 0.6941\n",
      "Epoch 20/30\n",
      "1383/1383 [==============================] - 0s 30us/step - loss: 0.5786 - acc: 0.7050\n",
      "Epoch 21/30\n",
      "1383/1383 [==============================] - 0s 31us/step - loss: 0.5657 - acc: 0.7115\n",
      "Epoch 22/30\n",
      "1383/1383 [==============================] - 0s 31us/step - loss: 0.5675 - acc: 0.7144\n",
      "Epoch 23/30\n",
      "1383/1383 [==============================] - 0s 31us/step - loss: 0.5466 - acc: 0.7498\n",
      "Epoch 24/30\n",
      "1383/1383 [==============================] - 0s 38us/step - loss: 0.5529 - acc: 0.7310\n",
      "Epoch 25/30\n",
      "1383/1383 [==============================] - 0s 30us/step - loss: 0.5291 - acc: 0.7477\n",
      "Epoch 26/30\n",
      "1383/1383 [==============================] - 0s 32us/step - loss: 0.5295 - acc: 0.7527\n",
      "Epoch 27/30\n",
      "1383/1383 [==============================] - 0s 32us/step - loss: 0.5265 - acc: 0.7527\n",
      "Epoch 28/30\n",
      "1383/1383 [==============================] - 0s 32us/step - loss: 0.5328 - acc: 0.7484\n",
      "Epoch 29/30\n",
      "1383/1383 [==============================] - 0s 32us/step - loss: 0.5121 - acc: 0.7643\n",
      "Epoch 30/30\n",
      "1383/1383 [==============================] - 0s 33us/step - loss: 0.5029 - acc: 0.7715\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<keras.callbacks.History at 0x7f0109805198>"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "smoke_detector_lbp_model.fit(training_set_lbp_feature, training_set_label, epochs=30)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Test LBP Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-12T08:38:38.256172Z",
     "start_time": "2018-05-12T08:38:38.201501Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1383/1383 [==============================] - 0s 37us/step\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[0.46117093777708273, 0.86695589302935983]"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "smoke_detector_lbp_model.evaluate(training_set_lbp_feature, training_set_label)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-12T08:38:39.671169Z",
     "start_time": "2018-05-12T08:38:39.604637Z"
    }
   },
   "outputs": [],
   "source": [
    "training_set_label_prediction_lbp = smoke_detector_lbp_model.predict(training_set_lbp_feature)\n",
    "test_set_label_prediction_lbp = smoke_detector_lbp_model.predict(test_set_lbp_feature)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-12T08:38:41.017840Z",
     "start_time": "2018-05-12T08:38:41.007933Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "混淆矩阵 Training Set\n",
      "    real/predict   True    False\n",
      "    \n",
      "    smoke          425     127\n",
      "    no smoke       774     57\n",
      "    检测率：0.769927536231884\n",
      "    虚警率：0.06859205776173286\n"
     ]
    }
   ],
   "source": [
    "training_set_label_prediction_lbp_positive = training_set_label_prediction_lbp[training_set_label == 1]\n",
    "training_set_label_prediction_lbp_negative = training_set_label_prediction_lbp[training_set_label == 0]\n",
    "\n",
    "training_set_label_prediction_lbp_positive_true = training_set_label_prediction_lbp_positive[training_set_label_prediction_lbp_positive >= 0.5]\n",
    "training_set_label_prediction_lbp_positive_false = training_set_label_prediction_lbp_positive[training_set_label_prediction_lbp_positive < 0.5]\n",
    "training_set_label_prediction_lbp_negative_true = training_set_label_prediction_lbp_negative[training_set_label_prediction_lbp_negative < 0.5]\n",
    "training_set_label_prediction_lbp_negative_false = training_set_label_prediction_lbp_negative[training_set_label_prediction_lbp_negative >= 0.5]\n",
    "\n",
    "print(\n",
    "    '''LBP+FC Training Set 混淆矩阵 Training Set\n",
    "    real/predict   True    False\n",
    "    \n",
    "    smoke          {0}     {1}\n",
    "    no smoke       {2}     {3}\n",
    "    检测率：{4}\n",
    "    虚警率：{5}'''.format(\n",
    "    training_set_label_prediction_lbp_positive_true.shape[0],\n",
    "    training_set_label_prediction_lbp_positive_false.shape[0],\n",
    "    training_set_label_prediction_lbp_negative_true.shape[0],\n",
    "    training_set_label_prediction_lbp_negative_false.shape[0],\n",
    "    training_set_label_prediction_lbp_positive_true.shape[0] / training_set_label_prediction_lbp_positive.shape[0],\n",
    "    training_set_label_prediction_lbp_negative_false.shape[0] / training_set_label_prediction_lbp_negative.shape[0]\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-12T08:38:42.559061Z",
     "start_time": "2018-05-12T08:38:42.550674Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "混淆矩阵 test Set\n",
      "    real/predict   True    False\n",
      "    \n",
      "    smoke          575     113\n",
      "    no smoke       804     13\n",
      "    检测率：0.8357558139534884\n",
      "    虚警率：0.01591187270501836\n"
     ]
    }
   ],
   "source": [
    "test_set_label_prediction_lbp_positive = test_set_label_prediction_lbp[test_set_label == 1]\n",
    "test_set_label_prediction_lbp_negative = test_set_label_prediction_lbp[test_set_label == 0]\n",
    "\n",
    "test_set_label_prediction_lbp_positive_true = test_set_label_prediction_lbp_positive[test_set_label_prediction_lbp_positive >= 0.5]\n",
    "test_set_label_prediction_lbp_positive_false = test_set_label_prediction_lbp_positive[test_set_label_prediction_lbp_positive < 0.5]\n",
    "test_set_label_prediction_lbp_negative_true = test_set_label_prediction_lbp_negative[test_set_label_prediction_lbp_negative < 0.5]\n",
    "test_set_label_prediction_lbp_negative_false = test_set_label_prediction_lbp_negative[test_set_label_prediction_lbp_negative >= 0.5]\n",
    "\n",
    "print(\n",
    "    '''LBP+FC Test Set 混淆矩阵 test Set\n",
    "    real/predict   True    False\n",
    "    \n",
    "    smoke          {0}     {1}\n",
    "    no smoke       {2}     {3}\n",
    "    检测率：{4}\n",
    "    虚警率：{5}'''.format(\n",
    "    test_set_label_prediction_lbp_positive_true.shape[0],\n",
    "    test_set_label_prediction_lbp_positive_false.shape[0],\n",
    "    test_set_label_prediction_lbp_negative_true.shape[0],\n",
    "    test_set_label_prediction_lbp_negative_false.shape[0],\n",
    "    test_set_label_prediction_lbp_positive_true.shape[0] / test_set_label_prediction_lbp_positive.shape[0],\n",
    "    test_set_label_prediction_lbp_negative_false.shape[0] / test_set_label_prediction_lbp_negative.shape[0]\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Extract Feature"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:29.674512Z",
     "start_time": "2018-05-14T12:58:29.670363Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_lbp_model_feature_extraction = Model(inputs=smoke_detector_lbp_input, outputs=smoke_detector_lbp_dense)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-12T08:38:46.148408Z",
     "start_time": "2018-05-12T08:38:46.100709Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1383, 128)"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "smoke_detector_lbp_model_feature_extraction.predict(training_set_lbp_feature).shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# VGG16"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get Feature"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-15T13:32:11.318814Z",
     "start_time": "2018-05-15T13:32:10.237958Z"
    }
   },
   "outputs": [],
   "source": [
    "from keras.applications.vgg16 import VGG16\n",
    "from keras.preprocessing import image\n",
    "from keras.applications.vgg16 import preprocess_input"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-15T13:32:27.979657Z",
     "start_time": "2018-05-15T13:32:14.069325Z"
    }
   },
   "outputs": [],
   "source": [
    "model_vgg16 = VGG16(input_shape=(224, 224, 3), include_top=False, weights='imagenet')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-12T01:47:37.391724Z",
     "start_time": "2018-05-12T01:47:35.963424Z"
    }
   },
   "outputs": [],
   "source": [
    "training_set_224 = np.array([cv2.resize(i, (224, 224)) for i in smoke_dataset_image_3]) * 255\n",
    "test_set_224 = np.array([cv2.resize(i, (224, 224)) for i in smoke_dataset_image_4]) * 255"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-12T07:41:24.477282Z",
     "start_time": "2018-05-12T07:31:42.036308Z"
    }
   },
   "outputs": [],
   "source": [
    "training_set_vgg16_feature = model_vgg16.predict(preprocess_input(training_set_224))\n",
    "#test_set_vgg16_feature = model_vgg16.predict(preprocess_input(test_set_224))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:37.754459Z",
     "start_time": "2018-05-14T12:58:37.750759Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_vgg16_input = Input(shape=(7, 7, 512,))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:38.640838Z",
     "start_time": "2018-05-14T12:58:38.630131Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_vgg16_flatten = Flatten()(smoke_detector_vgg16_input)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:39.052656Z",
     "start_time": "2018-05-14T12:58:39.043222Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_vgg16_dense_1 = Dense(1024, activation='sigmoid')(smoke_detector_vgg16_flatten)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:39.437309Z",
     "start_time": "2018-05-14T12:58:39.425995Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_vgg16_dropout_1 = Dropout(0.3)(smoke_detector_vgg16_dense_1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:39.802712Z",
     "start_time": "2018-05-14T12:58:39.793667Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_vgg16_dense_2 = Dense(128, activation='sigmoid')(smoke_detector_vgg16_dropout_1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:40.478368Z",
     "start_time": "2018-05-14T12:58:40.466709Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_vgg16_dropout_2 = Dropout(0.3)(smoke_detector_vgg16_dense_2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:41.170682Z",
     "start_time": "2018-05-14T12:58:41.158848Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_vgg16_prediction = Dense(1, activation='sigmoid')(smoke_detector_vgg16_dropout_2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:42.618966Z",
     "start_time": "2018-05-14T12:58:42.616071Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_vgg16_model = Model(inputs=smoke_detector_vgg16_input, outputs=smoke_detector_vgg16_prediction)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:43.076776Z",
     "start_time": "2018-05-14T12:58:43.045627Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_vgg16_model.compile(optimizer='AdaDelta',\n",
    "              loss='binary_crossentropy',\n",
    "              metrics=['accuracy'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-12T08:08:55.568080Z",
     "start_time": "2018-05-12T08:06:27.834126Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/10\n",
      "1383/1383 [==============================] - 15s 11ms/step - loss: 0.3060 - acc: 0.8670\n",
      "Epoch 2/10\n",
      "1383/1383 [==============================] - 15s 11ms/step - loss: 0.1095 - acc: 0.9559\n",
      "Epoch 3/10\n",
      "1383/1383 [==============================] - 15s 11ms/step - loss: 0.0685 - acc: 0.9754\n",
      "Epoch 4/10\n",
      "1383/1383 [==============================] - 15s 11ms/step - loss: 0.0521 - acc: 0.9834\n",
      "Epoch 5/10\n",
      "1383/1383 [==============================] - 15s 11ms/step - loss: 0.0326 - acc: 0.9899\n",
      "Epoch 6/10\n",
      "1383/1383 [==============================] - 15s 11ms/step - loss: 0.0245 - acc: 0.9935\n",
      "Epoch 7/10\n",
      "1383/1383 [==============================] - 15s 11ms/step - loss: 0.0185 - acc: 0.9913\n",
      "Epoch 8/10\n",
      "1383/1383 [==============================] - 15s 11ms/step - loss: 0.0149 - acc: 0.9964\n",
      "Epoch 9/10\n",
      "1383/1383 [==============================] - 15s 11ms/step - loss: 0.0127 - acc: 0.9964\n",
      "Epoch 10/10\n",
      "1383/1383 [==============================] - 15s 11ms/step - loss: 0.0085 - acc: 0.9986\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<keras.callbacks.History at 0x7f01cc5f3a20>"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "smoke_detector_vgg16_model.fit(training_set_vgg16_feature, training_set_label, epochs=10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Test VGG16 Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-12T08:23:22.461850Z",
     "start_time": "2018-05-12T08:11:41.459180Z"
    }
   },
   "outputs": [],
   "source": [
    "test_set_vgg16_feature = model_vgg16.predict(preprocess_input(test_set_224))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-12T08:23:31.039668Z",
     "start_time": "2018-05-12T08:23:28.530455Z"
    }
   },
   "outputs": [],
   "source": [
    "training_set_label_prediction_vgg16 = smoke_detector_vgg16_model.predict(training_set_vgg16_feature)\n",
    "test_set_label_prediction_vgg16 = smoke_detector_vgg16_model.predict(test_set_vgg16_feature)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-12T08:23:35.787160Z",
     "start_time": "2018-05-12T08:23:35.778119Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "混淆矩阵 Training Set\n",
      "    real/predict   True    False\n",
      "    \n",
      "    smoke          552     0\n",
      "    no smoke       831     0\n",
      "    检测率：1.0\n",
      "    虚警率：0.0\n"
     ]
    }
   ],
   "source": [
    "training_set_label_prediction_vgg16_positive = training_set_label_prediction_vgg16[training_set_label == 1]\n",
    "training_set_label_prediction_vgg16_negative = training_set_label_prediction_vgg16[training_set_label == 0]\n",
    "\n",
    "training_set_label_prediction_vgg16_positive_true = training_set_label_prediction_vgg16_positive[training_set_label_prediction_vgg16_positive >= 0.5]\n",
    "training_set_label_prediction_vgg16_positive_false = training_set_label_prediction_vgg16_positive[training_set_label_prediction_vgg16_positive < 0.5]\n",
    "training_set_label_prediction_vgg16_negative_true = training_set_label_prediction_vgg16_negative[training_set_label_prediction_vgg16_negative < 0.5]\n",
    "training_set_label_prediction_vgg16_negative_false = training_set_label_prediction_vgg16_negative[training_set_label_prediction_vgg16_negative >= 0.5]\n",
    "\n",
    "print(\n",
    "    '''VGG16+FC Training Set 混淆矩阵 Training Set\n",
    "    real/predict   True    False\n",
    "    \n",
    "    smoke          {0}     {1}\n",
    "    no smoke       {2}     {3}\n",
    "    检测率：{4}\n",
    "    虚警率：{5}'''.format(\n",
    "    training_set_label_prediction_vgg16_positive_true.shape[0],\n",
    "    training_set_label_prediction_vgg16_positive_false.shape[0],\n",
    "    training_set_label_prediction_vgg16_negative_true.shape[0],\n",
    "    training_set_label_prediction_vgg16_negative_false.shape[0],\n",
    "    training_set_label_prediction_vgg16_positive_true.shape[0] / training_set_label_prediction_vgg16_positive.shape[0],\n",
    "    training_set_label_prediction_vgg16_negative_false.shape[0] / training_set_label_prediction_vgg16_negative.shape[0]\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-12T08:23:36.827527Z",
     "start_time": "2018-05-12T08:23:36.818990Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "混淆矩阵 test Set\n",
      "    real/predict   True    False\n",
      "    \n",
      "    smoke          685     3\n",
      "    no smoke       786     31\n",
      "    检测率：0.9956395348837209\n",
      "    虚警率：0.037943696450428395\n"
     ]
    }
   ],
   "source": [
    "test_set_label_prediction_vgg16_positive = test_set_label_prediction_vgg16[test_set_label == 1]\n",
    "test_set_label_prediction_vgg16_negative = test_set_label_prediction_vgg16[test_set_label == 0]\n",
    "\n",
    "test_set_label_prediction_vgg16_positive_true = test_set_label_prediction_vgg16_positive[test_set_label_prediction_vgg16_positive >= 0.5]\n",
    "test_set_label_prediction_vgg16_positive_false = test_set_label_prediction_vgg16_positive[test_set_label_prediction_vgg16_positive < 0.5]\n",
    "test_set_label_prediction_vgg16_negative_true = test_set_label_prediction_vgg16_negative[test_set_label_prediction_vgg16_negative < 0.5]\n",
    "test_set_label_prediction_vgg16_negative_false = test_set_label_prediction_vgg16_negative[test_set_label_prediction_vgg16_negative >= 0.5]\n",
    "\n",
    "print(\n",
    "    '''VGG16+FC Test Set 混淆矩阵 test Set\n",
    "    real/predict   True    False\n",
    "    \n",
    "    smoke          {0}     {1}\n",
    "    no smoke       {2}     {3}\n",
    "    检测率：{4}\n",
    "    虚警率：{5}'''.format(\n",
    "    test_set_label_prediction_vgg16_positive_true.shape[0],\n",
    "    test_set_label_prediction_vgg16_positive_false.shape[0],\n",
    "    test_set_label_prediction_vgg16_negative_true.shape[0],\n",
    "    test_set_label_prediction_vgg16_negative_false.shape[0],\n",
    "    test_set_label_prediction_vgg16_positive_true.shape[0] / test_set_label_prediction_vgg16_positive.shape[0],\n",
    "    test_set_label_prediction_vgg16_negative_false.shape[0] / test_set_label_prediction_vgg16_negative.shape[0]\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Extract Feature"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:50.495347Z",
     "start_time": "2018-05-14T12:58:50.491234Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_vgg16_model_feature_extraction = Model(inputs=smoke_detector_vgg16_input, outputs=smoke_detector_vgg16_dense_2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-12T08:25:59.023208Z",
     "start_time": "2018-05-12T08:25:57.740645Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1383, 128)"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "smoke_detector_vgg16_model_feature_extraction.predict(training_set_vgg16_feature).shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Feature Fusion"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:53.351711Z",
     "start_time": "2018-05-14T12:58:53.349372Z"
    }
   },
   "outputs": [],
   "source": [
    "from keras.layers import concatenate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:53.910926Z",
     "start_time": "2018-05-14T12:58:53.907373Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_feature_fusion_concat = concatenate([smoke_detector_hog_model_feature_extraction.output, smoke_detector_lbp_model_feature_extraction.output, smoke_detector_vgg16_model_feature_extraction.output])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:54.669937Z",
     "start_time": "2018-05-14T12:58:54.660981Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_feature_fusion_dense_1 = Dense(16, activation='sigmoid')(smoke_detector_feature_fusion_concat)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:55.095274Z",
     "start_time": "2018-05-14T12:58:55.082916Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_feature_fusion_dropout_1 = Dropout(0.2)(smoke_detector_feature_fusion_dense_1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:55.882708Z",
     "start_time": "2018-05-14T12:58:55.873616Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_feature_fusion_prediction = Dense(1, activation='sigmoid')(smoke_detector_feature_fusion_dropout_1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:56.344825Z",
     "start_time": "2018-05-14T12:58:56.342390Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_feature_fusion_model = Model(inputs=[smoke_detector_hog_input, smoke_detector_lbp_input, smoke_detector_vgg16_input], outputs=[smoke_detector_feature_fusion_prediction])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:58:57.519607Z",
     "start_time": "2018-05-14T12:58:57.495120Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_feature_fusion_model.compile(optimizer='AdaDelta',\n",
    "              loss='binary_crossentropy',\n",
    "              metrics=['accuracy'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-13T06:02:03.593371Z",
     "start_time": "2018-05-13T06:00:49.121044Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/5\n",
      "1383/1383 [==============================] - 15s 11ms/step - loss: 0.0130 - acc: 1.0000\n",
      "Epoch 2/5\n",
      "1383/1383 [==============================] - 15s 11ms/step - loss: 0.0113 - acc: 1.0000\n",
      "Epoch 3/5\n",
      "1383/1383 [==============================] - 15s 11ms/step - loss: 0.0087 - acc: 1.0000\n",
      "Epoch 4/5\n",
      "1383/1383 [==============================] - 15s 11ms/step - loss: 0.0081 - acc: 1.0000\n",
      "Epoch 5/5\n",
      "1383/1383 [==============================] - 15s 11ms/step - loss: 0.0068 - acc: 1.0000\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<keras.callbacks.History at 0x7f0107fc2550>"
      ]
     },
     "execution_count": 92,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "smoke_detector_feature_fusion_model.fit([training_set_hog_feature, training_set_lbp_feature, training_set_vgg16_feature], training_set_label, epochs=10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:59:04.213215Z",
     "start_time": "2018-05-14T12:59:04.211284Z"
    }
   },
   "outputs": [],
   "source": [
    "from keras.utils.vis_utils import plot_model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-14T12:59:05.870457Z",
     "start_time": "2018-05-14T12:59:05.480796Z"
    }
   },
   "outputs": [],
   "source": [
    "plot_model(smoke_detector_feature_fusion_model, to_file='model.png', show_shapes=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-13T05:55:12.995564Z",
     "start_time": "2018-05-13T05:55:05.492217Z"
    }
   },
   "outputs": [],
   "source": [
    "smoke_detector_hog_model.save('model/smoke_detector_hog_model.h5')\n",
    "smoke_detector_lbp_model.save('model/smoke_detector_lbp_model.h5')\n",
    "smoke_detector_vgg16_model.save('model/smoke_detector_vgg16_model.h5')\n",
    "smoke_detector_feature_fusion_model.save('model/smoke_detector_feature_fusion_model.h5')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Test Feature Fusion Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-13T06:02:14.723050Z",
     "start_time": "2018-05-13T06:02:12.155162Z"
    }
   },
   "outputs": [],
   "source": [
    "training_set_label_prediction_feature_fusion = smoke_detector_feature_fusion_model.predict([training_set_hog_feature, training_set_lbp_feature, training_set_vgg16_feature])\n",
    "test_set_label_prediction_feature_fusion = smoke_detector_feature_fusion_model.predict([test_set_hog_feature, test_set_lbp_feature, test_set_vgg16_feature])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-13T06:02:16.809639Z",
     "start_time": "2018-05-13T06:02:16.800822Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "混淆矩阵 Training Set\n",
      "    real/predict   True    False\n",
      "    \n",
      "    smoke          552     0\n",
      "    no smoke       831     0\n",
      "    检测率：1.0\n",
      "    虚警率：0.0\n"
     ]
    }
   ],
   "source": [
    "training_set_label_prediction_feature_fusion_positive = training_set_label_prediction_feature_fusion[training_set_label == 1]\n",
    "training_set_label_prediction_feature_fusion_negative = training_set_label_prediction_feature_fusion[training_set_label == 0]\n",
    "\n",
    "training_set_label_prediction_feature_fusion_positive_true = training_set_label_prediction_feature_fusion_positive[training_set_label_prediction_feature_fusion_positive >= 0.5]\n",
    "training_set_label_prediction_feature_fusion_positive_false = training_set_label_prediction_feature_fusion_positive[training_set_label_prediction_feature_fusion_positive < 0.5]\n",
    "training_set_label_prediction_feature_fusion_negative_true = training_set_label_prediction_feature_fusion_negative[training_set_label_prediction_feature_fusion_negative < 0.5]\n",
    "training_set_label_prediction_feature_fusion_negative_false = training_set_label_prediction_feature_fusion_negative[training_set_label_prediction_feature_fusion_negative >= 0.5]\n",
    "\n",
    "print(\n",
    "    '''Feature Fusion+FC Training Set 混淆矩阵 Training Set\n",
    "    real/predict   True    False\n",
    "    \n",
    "    smoke          {0}     {1}\n",
    "    no smoke       {2}     {3}\n",
    "    检测率：{4}\n",
    "    虚警率：{5}'''.format(\n",
    "    training_set_label_prediction_feature_fusion_positive_true.shape[0],\n",
    "    training_set_label_prediction_feature_fusion_positive_false.shape[0],\n",
    "    training_set_label_prediction_feature_fusion_negative_true.shape[0],\n",
    "    training_set_label_prediction_feature_fusion_negative_false.shape[0],\n",
    "    training_set_label_prediction_feature_fusion_positive_true.shape[0] / training_set_label_prediction_feature_fusion_positive.shape[0],\n",
    "    training_set_label_prediction_feature_fusion_negative_false.shape[0] / training_set_label_prediction_feature_fusion_negative.shape[0]\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-05-13T06:02:18.918436Z",
     "start_time": "2018-05-13T06:02:18.909641Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "混淆矩阵 test Set\n",
      "    real/predict   True    False\n",
      "    \n",
      "    smoke          684     4\n",
      "    no smoke       785     32\n",
      "    检测率：0.9941860465116279\n",
      "    虚警率：0.03916768665850673\n"
     ]
    }
   ],
   "source": [
    "test_set_label_prediction_feature_fusion_positive = test_set_label_prediction_feature_fusion[test_set_label == 1]\n",
    "test_set_label_prediction_feature_fusion_negative = test_set_label_prediction_feature_fusion[test_set_label == 0]\n",
    "\n",
    "test_set_label_prediction_feature_fusion_positive_true = test_set_label_prediction_feature_fusion_positive[test_set_label_prediction_feature_fusion_positive >= 0.5]\n",
    "test_set_label_prediction_feature_fusion_positive_false = test_set_label_prediction_feature_fusion_positive[test_set_label_prediction_feature_fusion_positive < 0.5]\n",
    "test_set_label_prediction_feature_fusion_negative_true = test_set_label_prediction_feature_fusion_negative[test_set_label_prediction_feature_fusion_negative < 0.5]\n",
    "test_set_label_prediction_feature_fusion_negative_false = test_set_label_prediction_feature_fusion_negative[test_set_label_prediction_feature_fusion_negative >= 0.5]\n",
    "\n",
    "print(\n",
    "    '''Feature Fusion+FC Test Set 混淆矩阵 test Set\n",
    "    real/predict   True    False\n",
    "    \n",
    "    smoke          {0}     {1}\n",
    "    no smoke       {2}     {3}\n",
    "    检测率：{4}\n",
    "    虚警率：{5}'''.format(\n",
    "    test_set_label_prediction_feature_fusion_positive_true.shape[0],\n",
    "    test_set_label_prediction_feature_fusion_positive_false.shape[0],\n",
    "    test_set_label_prediction_feature_fusion_negative_true.shape[0],\n",
    "    test_set_label_prediction_feature_fusion_negative_false.shape[0],\n",
    "    test_set_label_prediction_feature_fusion_positive_true.shape[0] / test_set_label_prediction_feature_fusion_positive.shape[0],\n",
    "    test_set_label_prediction_feature_fusion_negative_false.shape[0] / test_set_label_prediction_feature_fusion_negative.shape[0]\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "hide_input": false,
  "kernelspec": {
   "display_name": "Python [conda root]",
   "language": "python",
   "name": "conda-root-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  },
  "latex_envs": {
   "LaTeX_envs_menu_present": true,
   "autoclose": true,
   "autocomplete": true,
   "bibliofile": "biblio.bib",
   "cite_by": "apalike",
   "current_citInitial": 1,
   "eqLabelWithNumbers": true,
   "eqNumInitial": 1,
   "hotkeys": {
    "equation": "Ctrl-E",
    "itemize": "Ctrl-I"
   },
   "labels_anchors": false,
   "latex_user_defs": false,
   "report_style_numbering": false,
   "user_envs_cfg": false
  },
  "toc": {
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": "block",
   "toc_window_display": false
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
